using System.Web;
using LogikBug.ModularMvc.Locations;

namespace LogikBug.ModularMvc.Factories
{
	/// <summary>
	/// Proviced methods for creating <see cref="ILocation"/>s.
	/// </summary>
	public sealed class LocationFactory
	{
		#region Fields

		private static volatile LocationFactory _locations;
		private static readonly object LockObj = new object();

		#endregion

		#region Constructors

		private LocationFactory()
		{
		}

		#endregion

		#region Properties

		/// <summary>
		/// The singleton instance for the <see cref="LocationFactory"/> class.
		/// </summary>
		public static LocationFactory Instance
		{
			get
			{
				if (_locations == null)
				{
					lock (LockObj)
					{
						if (_locations == null)
						{
							_locations = new LocationFactory();
						}
					}
				}

				return _locations;
			}
		}

		#endregion

		#region Methods

		/// <summary>
		/// Creates a <see cref="DirectoryLocation"/> using the Bin directory.
		/// </summary>
		/// <returns>An <see cref="ILocation"/> containing the paths to all assemblies in the Bin directory.</returns>
		public ILocation FromBin()
		{
			return new DirectoryLocation(HttpRuntime.BinDirectory);
		}

		/// <summary>
		/// Creates a <see cref="DirectoryLocation"/> using the Codegen directory.
		/// </summary>
		/// <returns>An <see cref="ILocation"/> containing the paths to all assemblies in the Codegen directory.</returns>
		public ILocation FromCodegenDir()
		{
			return new DirectoryLocation(HttpRuntime.CodegenDir);
		}

		/// <summary>
		/// Creates a <see cref="DirectoryLocation"/> using the virtual path.
		/// </summary>
		/// <returns>An <see cref="ILocation"/> containing the paths to all assemblies in the virtual path.</returns>
		public ILocation FromVirtualPath(string path)
		{
			return new DirectoryLocation(HttpContext.Current.Server.MapPath(path));
		}

		///// <summary>
		///// Creates a <see cref="MongoLocation{T}"/> using the specified configurations.
		///// </summary>
		///// <typeparam name="T">The type used in the query.</typeparam>
		///// <param name="connectionString">The <see cref="ConnectionString"/> object used to connect to MongoDB.</param>
		///// <param name="selector">The filter used in the query.</param>
		///// <returns>An <see cref="ILocation{T}"/> initialized with the current configuration.</returns>
		//public ILocation<T> Mongo<T>(IConnectionString connectionString, Func<T, bool> selector) where T : class, IReference, new()
		//{
		//    var location = new MongoLocation<T>(connectionString);
		//    location.WithQuery(selector);
		//    return location;
		//}

		///// <summary>
		///// Creates a <see cref="MongoLocation{T}"/> using the specified configurations.
		///// </summary>
		///// <typeparam name="T">The type used in the query.</typeparam>
		///// <returns>An <see cref="ILocation{T}"/> initialized with the current configuration.</returns>
		//public ILocation<T> Mongo<T>(IEnumerable<T> collection) where T : class, IReference, new()
		//{
		//    var location = new MongoLocation<T>(connectionString);
		//    location.WithQuery(selector);
		//    return location;
		//}

		#endregion
	}
}